package visualizer.input.concrete;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import processing.core.PGraphics;
import processing.core.PImage;
import processing.core.PVector;
import visualizer.countries.CountryMap;
import visualizer.countries.RegionMap;
import visualizer.data.DataSource;
import visualizer.graphics.HsbColor;
import visualizer.graphics.MagicWand;
import visualizer.graphics.Mask;
import visualizer.graphics.MaskFiller;
import visualizer.graphics.Point;
import visualizer.input.Component;

public class CountryComponent extends Component {
	private Map<Point, Mask> masks = new HashMap<Point, Mask>();
	private Map<Integer, MaskFiller> fillers = new HashMap<Integer, MaskFiller>();
	private MagicWand selector = new MagicWand(0);
	
	private CountryMap countries = new CountryMap();
	private RegionMap regions = new RegionMap();
	private PImage countryGraphic;
	private PVector offset;
	private DataSource<Map<String, Integer>> colors;
	
	public CountryComponent(PVector position, PImage countryGraphic, PVector offset, DataSource<Map<String, Integer>> colors) {
		super(position, new PVector(countryGraphic.width, countryGraphic.height));
		this.countryGraphic = countryGraphic;
		this.offset = offset;
		this.colors = colors;
	}
	
	public CountryComponent setCountryColorMap(Map<String, Integer> colors)
	{
		this.colors.set(colors);
		return this;
	}
	
	protected void drawRelative(PGraphics g) {
		g.noSmooth();
		
		for (Map.Entry<String, List<PVector>> e : countries.entrySet()) {
			int countryColor = getColor(e.getKey());
			for (PVector v : e.getValue()) {
				fill(v, countryColor);
			}
		}
		g.colorMode(g.RGB);
		g.image(countryGraphic, 0, 0, countryGraphic.width, countryGraphic.height);
	}
	
	public void fill(PVector p, int color)
	{
		MaskFiller f = getFiller(color);
		f.fill(getMask(p), countryGraphic);
	}
	
	public int getColor(String country)
	{
		if (colors.get().containsKey(country)) {
			return colors.get().get(country);
		}
		return 0;
	}
	
	public Mask getMask(PVector v)
	{
		Point p = new Point(v);
		
		if (!masks.containsKey(p)) {
			masks.put(p, createMask(p));
		}

		return masks.get(p);
	}
	
	public Mask createMask(Point p)
	{
		return selector.select(p, countryGraphic);
	}
	
	public MaskFiller getFiller(int color)
	{
		if (!fillers.containsKey(color)) {
			fillers.put(color, createFiller(color));
		}
		return fillers.get(color);
	}
	
	public MaskFiller createFiller(int color)
	{
		return new MaskFiller(color);
	}
}
